package com.brillilab.starter.controller.aio.experiments;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.brillilab.common.entity.ResponseVo;
import com.brillilab.domain.enums.common.BoolEnum;
import com.brillilab.domain.enums.kit.KitEnum.Classify;
import com.brillilab.domain.po.experiments.Experiment;
import com.brillilab.domain.po.experiments.ExperimentBill;
import com.brillilab.domain.vo.experiments.ExperimentBillListVo;
import com.brillilab.domain.vo.experiments.ExperimentDtailsVo;
import com.brillilab.domain.vo.experiments.ExperimentHeadModifyVo;
import com.brillilab.domain.vo.experiments.ExperimentProduceSaveListVo;
import com.brillilab.domain.vo.experiments.ExperimentStepModifyVo;
import com.brillilab.domain.vo.experiments.ExperimentStepSaveVo;
import com.brillilab.domain.vo.kit.SampleSpecVo;
import com.brillilab.domain.vo.user.UserInfoVo;
import com.brillilab.service.core.experiments.IExperimentBillService;
import com.brillilab.service.core.experiments.IExperimentPhaseService;
import com.brillilab.service.core.experiments.IExperimentService;
import com.brillilab.service.core.system.IDictService;
import com.brillilab.service.logic.experiments.ExperimentLogic;
import com.brillilab.service.logic.user.UsersLogic;
import com.brillilab.starter.aspect.AspectLog;
import com.brillilab.starter.constant.StarterConstant;

@RestController
@RequestMapping("/api/experiment/info")
public class ExperimentInfoController {
	
	@Autowired
    private UsersLogic usersLogic;
	@Autowired
	private ExperimentLogic experimentLogic;
	@Autowired
	private IExperimentBillService experimentBillService;
	@Autowired
	private IExperimentService experimentService;
	@Autowired
	private IDictService dictService;
	@Autowired
	private IExperimentPhaseService experimentPhaseService;
	
	/**
	 * 获取实验清单列表
	 * 
	 * @return
	 */
	@GetMapping("/billList")
	public ResponseVo billList( @RequestParam Long experimentId,
			@RequestHeader(name = StarterConstant.TOKEN) String token) {
		Map<Integer, String> unitMap = dictService.getUnitMap();
		ExperimentBillListVo billVo = new ExperimentBillListVo();
		List<ExperimentBill> list = experimentBillService.selectList(experimentId);
		if(!CollectionUtils.isEmpty(list)) {
			List<ExperimentBill> reagentList = new ArrayList<>();
			List<ExperimentBill> sampleList = new ArrayList<>();
			list.forEach(bill -> {
				bill.setUnitName(unitMap.get(bill.getUnit()));
				if(bill.getClassify().equals(Classify.REAGENT.getValue())) {
					reagentList.add(bill);
				}else if(bill.getClassify().equals(Classify.SAMPLE.getValue())) {
					sampleList.add(bill);
				}
			});
			billVo.setReagentList(reagentList);
			billVo.setSampleList(sampleList);
		}
		return ResponseVo.success(billVo);
	}
	
	/**
	 * 获取实验信息详情
	 * 
	 * @return
	 */
	@GetMapping("/details")
	public ResponseVo experimentDtails( @RequestParam Long experimentId,
			@RequestHeader(name = StarterConstant.TOKEN) String token) {
		UserInfoVo userInfo = usersLogic.getUserByToken(token);
		ExperimentDtailsVo dtailsVo = experimentLogic.getExperimentDtails(userInfo,experimentId);
		return ResponseVo.success(dtailsVo);
	}
	
	/**
	 * 根据实验目标ID获取正在进行中的实验信息详情
	 * 
	 * @return
	 */
	@GetMapping("/underWay/details")
	public ResponseVo experimentUnderWayDtails( @RequestParam Long experimentTargetId,
			@RequestHeader(name = StarterConstant.TOKEN) String token) {
		UserInfoVo userInfo = usersLogic.getUserByToken(token);
		ExperimentDtailsVo dtailsVo = null;
		Experiment experiment = experimentService.getUnderWayOrNotStarted(experimentTargetId);
		if(experiment!=null) {
			dtailsVo = experimentLogic.getExperimentDtails(userInfo, experiment.getId());
		}
		return ResponseVo.success(dtailsVo);
	}
	
	/**
	 * 实验中 头部信息修改 (阶段名/注释 实验名/概述 )
	 * 
	 * @return
	 */
	@AspectLog
	@PostMapping("/step/headModify")
	public ResponseVo headModify(@RequestBody  ExperimentHeadModifyVo modifyVo,
			@RequestHeader(name = StarterConstant.TOKEN) String token) {
		 experimentLogic.experimentHeadModify(modifyVo);
		return ResponseVo.success();
	}
	
	/**
	 * 实验中 步骤内容修改
	 * 
	 * @return
	 */
	@AspectLog
	@PostMapping("/step/modify")
	public ResponseVo stepModify(@RequestBody  ExperimentStepModifyVo modifyVo,
			@RequestHeader(name = StarterConstant.TOKEN) String token) {
		experimentLogic.experimentStepModify(modifyVo);
		return ResponseVo.success();
	}
	
	/**
	 * 实验中 插入步骤
	 * 
	 * @return
	 */
	@AspectLog
	@PostMapping("/step/insert")
	public ResponseVo stepInsert(@RequestBody  ExperimentStepSaveVo saveVo,
			@RequestHeader(name = StarterConstant.TOKEN) String token) {
		Long stepId = experimentLogic.experimentStepInsert(saveVo);
		return ResponseVo.successMap("stepId", stepId);
	}
	/**
	 * 实验中 删除步骤
	 * 
	 * @return
	 */
	@AspectLog
	@GetMapping("/step/delete")
	public ResponseVo stepDelete(@RequestParam Long stepId,
			@RequestHeader(name = StarterConstant.TOKEN) String token) {
		Long experimentStepId = experimentLogic.experimentStepDelete(stepId);
		return ResponseVo.successMap("experimentStepId", experimentStepId);
	}
	

	/**
	 * 结束实验
	 *
	 * @return
	 */
	@AspectLog
	@GetMapping("/endExperiment")
	public ResponseVo endExperiment(@RequestParam Long experimentId, @RequestParam(defaultValue="0") int isSaveMethod,
			Integer isExpect,
			@RequestHeader(name = StarterConstant.TOKEN) String token) {
		UserInfoVo userInfo = usersLogic.getUserByToken(token);
		experimentLogic.experimentEnd(userInfo, experimentId, isSaveMethod,isExpect);
		return ResponseVo.success();
	}
	
	
	/**
	 * 重复实验步骤
	 * @param stepId
	 * @param isCurrent 0-重复当前步骤，1-后续全部步骤
	 */
	@AspectLog
	@GetMapping("/stepRepeat")
	public ResponseVo experimentStepRepeat(@RequestParam Long stepId, @RequestParam int isCurrent,
			@RequestHeader(name = StarterConstant.TOKEN) String token) {
		UserInfoVo userInfo = usersLogic.getUserByToken(token);
		experimentLogic.experimentStepRepeat(stepId, isCurrent,userInfo);
		return ResponseVo.success();
	}
	
	
	/**
	 * 保存实验样品产物
	 * 
	 * @return
	 */
	@AspectLog
	@PostMapping("/produceSave")
	public ResponseVo produceSave(@RequestHeader(name=StarterConstant.TOKEN) String token,@RequestBody ExperimentProduceSaveListVo saveListVo) {
		UserInfoVo urs=usersLogic.getUserByToken(token);
		saveListVo.setLabId(urs.getLabId());
		saveListVo.setCreatorId(urs.getLabMemberId());
		List<SampleSpecVo> list = experimentLogic.produceSave(saveListVo,urs);
		return ResponseVo.success(list);
	}
	
	
	/**
	 * 判断是否新方法
	 * 
	 * @param experimentId
	 * @param token
	 * @return
	 */
	@GetMapping("/isNewMethod")
	public ResponseVo isNewMethod(@RequestParam Long experimentId,
			@RequestHeader(name = StarterConstant.TOKEN) String token) {
		Experiment experiment = experimentService.selectById(experimentId);
		Assert.notNull(experiment, "实验信息不存在");
		
		if(BoolEnum.FALSE.getValue().equals(experiment.getIsNewMethod()) 
				&& experiment.getMethodId()==null) {
			int count = experimentPhaseService.selectCount(experiment.getId());
			if(count>0) {
				return ResponseVo.successMap("isNewMethod", BoolEnum.TRUE.getValue());	
			}
		}
		return ResponseVo.successMap("isNewMethod", experiment.getIsNewMethod());
	}


}
